package com.drakulo.games.ais.ui.component.window;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.newdawn.slick.Color;
import org.newdawn.slick.Font;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

import com.drakulo.games.ais.core.GameData;
import com.drakulo.games.ais.core.Resource;
import com.drakulo.games.ais.core.building.BuildingCategory;
import com.drakulo.games.ais.core.building.BuildingData;
import com.drakulo.games.ais.core.building.BuildingHelper;
import com.drakulo.games.ais.core.building.BuildingType;
import com.drakulo.games.ais.core.delayed.BuildingAction;
import com.drakulo.games.ais.core.delayed.PreparationAction;
import com.drakulo.games.ais.core.io.BuildingIO;
import com.drakulo.games.ais.ui.FontHelper;
import com.drakulo.games.ais.ui.I18n;
import com.drakulo.games.ais.ui.Style;
import com.drakulo.games.ais.ui.UIHelper;
import com.drakulo.games.ais.ui.component.ActionHandler;
import com.drakulo.games.ais.ui.component.UIComponent;
import com.drakulo.games.ais.ui.component.button.Button;
import com.drakulo.games.ais.ui.component.button.ImageButton;
import com.drakulo.games.ais.ui.state.SectorState;

/**
 * UIComponent for rendering the building selection window
 * 
 * @author Drakulo
 * 
 */
public class BuildWindowOld extends UIComponent {
	/** Industrial buildings buttons */
	private List<Button> buttons;
	/** Special handling for the command center button */
	private Button cmButton;
	/** The play state */
	private SectorState parent;

	private Map<Resource, BigDecimal> cost;
	private Map<Resource, BigDecimal> prod;
	private Map<Resource, BigDecimal> store;
	private String name;
	/** Flag indicating if the command center is built */
	private boolean commandCenterBuilt;

	/**
	 * Constructor
	 * 
	 * @param width
	 *            The window width
	 * @param height
	 *            The window height
	 */
	public BuildWindowOld(SectorState parent, int width, int height, int ox, int oy) {
		this.setOX(ox);
		this.setOY(oy);
		this.setWidth(width);
		this.setHeight(height);
		this.parent = parent;
		this.buttons = new ArrayList<Button>();
		this.name = "";
		this.cost = new HashMap<Resource, BigDecimal>();
		this.prod = new HashMap<Resource, BigDecimal>();
		this.store = new HashMap<Resource, BigDecimal>();
		initMaps();

		final int pitch = ImageButton.IB_DEFAULT_SIZE + 2;
		final int initialX = getOX() + 10;
		final int initialY = getOY() + 10;
		int x = initialX;
		int y = initialY;

		// Robots actions
		// Terrabot (terrain preparation)

		Button terrabotButton = new ImageButton("TERRABOT", x, y);
		terrabotButton.disable();
		// TODO why the terrabutton size is fucked?
		terrabotButton.setSize(ImageButton.IB_DEFAULT_SIZE,
				ImageButton.IB_DEFAULT_SIZE);
		terrabotButton.setActionHandler(new ActionHandler() {

			@Override
			public void run() {
				PreparationAction pa = BuildingHelper.create(GameData.getSelectedColony());
				BuildWindowOld.this.parent.setSelectedAction(pa);
				hide();
			}
		});
		terrabotButton.setHoverHandler(new ActionHandler() {

			@Override
			public void run() {
				initMaps();
				BuildWindowOld.this.name = "terrabot";
				BuildWindowOld.this.cost.put(Resource.ENERGY,
						BigDecimal.valueOf(25));
			}
		});
		this.buttons.add(terrabotButton);

		// Landscape buildings, following the robots with a little margin
		x += pitch * 2; // The margin
		List<BuildingType> types = BuildingType
				.values(BuildingCategory.LANDSCAPE);
		for (BuildingType type : types) {
			Button button = createBuildingButton(type.toString()
					.substring(0, 1), type);
			button.setPosition(x, y);
			this.buttons.add(button);
			x += pitch;
		}

		// Industrial buildings
		x = initialX;
		y += pitch;
		types = BuildingType.values(BuildingCategory.INDUSTRIAL);
		for (BuildingType type : types) {
			Button button = createBuildingButton(type.toString()
					.substring(0, 1), type);
			button.setPosition(x, y);
			this.buttons.add(button);
			x += pitch;
		}

		// Civil buildings
		x = initialX;
		y += pitch;
		types = BuildingType.values(BuildingCategory.CIVIL);
		for (BuildingType type : types) {
			Button button = createBuildingButton(type.toString()
					.substring(0, 1), type);
			button.setPosition(x, y);
			if (BuildingType.COMMAND_CENTER.equals(type)) {
				this.cmButton = button;
				this.cmButton.enable();
				if (GameData.getSelectedColony().isCommandCenterBuilt()) {
					// Only 1 command center
					button.disable();
				}
			} else if (BuildingType.RESEARCH_CENTER.equals(type)
					&& GameData.getSelectedColony().isResearchCenterBuilt()) {
				// Only 1 research center
				button.disable();
			}
			this.buttons.add(button);
			x += pitch;
		}

	}

	private Button createBuildingButton(String text, final BuildingType type) {
		ImageButton button = new ImageButton(type.toString());
		button.setActionHandler(new ActionHandler() {

			@Override
			public void run() {
				BuildingAction ba = BuildingHelper.createAction(GameData.getSelectedColony(), type,
						BuildWindowOld.this.cost);
				BuildWindowOld.this.parent.setSelectedAction(ba);
				hide();
			}
		});
		button.setHoverHandler(new ActionHandler() {

			@Override
			public void run() {
				displayBuildingData(type);
			}
		});
		button.disable();
		return button;
	}

	@Override
	public void render(Graphics g) throws SlickException {
		// System.out.println(this.getOX()+"-"+
		// this.getOY()+"-"+this.getWidth()+"-"+this.getHeight());
		UIHelper.drawBox(g, this.getOX(), this.getOY(), this.getWidth(),
				this.getHeight());
		UIHelper.drawWindow(g, getOX(), getOY(), getWidth(), 140, 5);

		for (Button b : this.buttons) {
			b.render(g);
		}

		// Rendering of the information zone
		Font font = FontHelper.getDefaultFont();
		final int padding = 10;
		int y = this.getOY() + 140;
		int x = this.getOX() + padding;

		g.setColor(Style.BORDER_COLOR);
		g.drawLine(x, y, this.getOX() + this.width - padding, y);

		y += 10;
		g.setColor(Color.black);
		font.drawString(this.getOX() + 10, y, this.name);

		y += 20;
		font.drawString(x + 100, y, I18n.getFirstToUpper("resource.price"));
		font.drawString(x + 200, y, I18n.getFirstToUpper("resource.income"));
		font.drawString(x + 300, y, I18n.getFirstToUpper("resource.store"));

		y += 20;
		g.drawLine(x, y, this.getOX() + 400, y);
		final int pitch = 20;
		Resource[] resources = Resource.values();
		for (Resource r : resources) {
			font.drawString(x, y, FontHelper.firstToUpper(r.getI18n()));

			font.drawString(x + 100, y, this.cost.get(r).toString() + " U");
			font.drawString(x + 200, y, this.prod.get(r).toString() + " UPM");
			font.drawString(x + 300, y, this.store.get(r).toString() + " U");
			y += pitch;
		}
	}

	@Override
	public void update(Input input) throws SlickException {
		for (Button b : this.buttons) {
			b.update(input);
		}
	}

	private void displayBuildingData(BuildingType type) {
		String name = FontHelper.firstToUpper(I18n.get(type.getI18n()));
		if (this.name.equals(name)) {
			return;
		}
		this.name = name;
		BuildingData data = BuildingIO.getBuildingData(type);
		BuildingHelper.copyMap(data.getLevelData(1).getProduction(), this.prod);
		BuildingHelper
				.copyMap(data.getLevelData(0).getUpgradeCost(), this.cost);
		BuildingHelper.copyMap(data.getLevelData(1).getStoreCapacity(),
				this.store);
	}

	private void initMaps() {
		Resource[] resources = Resource.values();
		for (Resource r : resources) {
			this.cost.put(r, BigDecimal.ZERO);
			this.prod.put(r, BigDecimal.ZERO);
			this.store.put(r, BigDecimal.ZERO);
		}
	}

	public void setCommandCenterBuilt(boolean value) {
		if(this.commandCenterBuilt == value){
			return;
		}
		this.commandCenterBuilt = value;
		for(Button b : this.buttons){
			if(value){
				b.enable();
			}else{
				b.disable();
			}
		}
		
		if(value){
			this.cmButton.disable();
		}else{
			this.cmButton.enable();
		}
	}
}
